package com.gexin.service.memberAcitivty;

import com.alibaba.fastjson.JSONObject;
import com.gexin.common.AppGlobal;
import com.gexin.common.model.ApiResponse;
import com.gexin.common.utils.BigDecimalUtils;
import com.gexin.common.utils.StringUtil;
import com.gexin.common.utils.UUIDUtils;
import com.gexin.model.activity.*;
import com.gexin.model.enums.MemberInfoEnum;
import com.gexin.model.order.Order;
import com.gexin.model.order.OrderItem;
import com.gexin.model.product.ProductSku;
import com.gexin.model.product.Products;
import com.gexin.model.shop.ShopInfo;
import com.gexin.model.template.TemplateArea;
import com.gexin.model.weixin.UserAddress;
import com.jfinal.aop.Before;
import com.jfinal.plugin.activerecord.tx.Tx;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.gexin.common.utils.ArithUtil.percent;
import static org.aspectj.bridge.MessageUtil.fail;


public class CashCoupService {


    /**
     * 积分明细(会员)
     *
     * @param id
     * @param status
     * @return
     */
    public List integralOrder(String id, int status) {
        List list = new ArrayList();
        if (status == 1) {
            List<MemberIntegralLog> memberIntegralLogs = MemberIntegralLog.dao.getMemberIntegralLogs(id);
            list.addAll(memberIntegralLogs);
        }
        if (status == 0) {
            List<MemberCashCouponLog> memberCashCouponLog = MemberCashCouponLog.dao.findByUserId(id);
            list.addAll(memberCashCouponLog);
        }
        return list;
    }


    /**
     * 积分明细(游客)
     *
     * @param id
     * @param status
     * @return
     */
    public List vistorIntegralOrder(String id, int status) {
        List list = new ArrayList();
        if (status == 1) {
            List<VistorOrder> vistorOrderList = VistorOrder.dao.getVistorOrderList();
            List<Order> orderListByUserIdAndStatus = Order.dao.getOrderListByUserIdAndStatus(3, id);
            Map<String, Order> orderMap = orderListByUserIdAndStatus.stream().collect(Collectors.toMap(
                    Order::getId, Function.identity(), (key1, key2) -> key2));
            List<VistorOrder> collect = vistorOrderList.stream().filter(vistorOrder -> vistorOrder.getOrderId()
                    != null && vistorOrder.getStatus() == 2 && orderMap.get(vistorOrder.getOrderId()) != null).
                    collect(Collectors.toList());
            list.addAll(collect);
        }
        if (status == 0) {
            List<VistorIntegralLog> vistorIntegralLogList = VistorIntegralLog.dao.findList(id);
            list.addAll(vistorIntegralLogList);
    }
        return list;
    }

    /**
     * 获取积分专区所有商品
     *
     * @return
     */
    public Map getIntegralRegionAllProduct() {
        List<IntegralRewardRegion> integralExchangeRegionList = IntegralRewardRegion.dao.findAll();
        Map<Integer, List<IntegralRewardRegion>> collect = integralExchangeRegionList.stream().collect(Collectors.groupingBy(IntegralRewardRegion::getType));
        return collect;
    }


    /**
     * 积分兑换商品
     *
     * @param num
     * @param userId
     * @param productId
     * @return
     */
    public ApiResponse integralExchangeProduct(String userId, int productId, int num, String phone,
                                               int addressId, int xapp) {
        try {
            IntegralRewardRegion product = IntegralRewardRegion.dao.getIntegralRewardRegion(productId + "");
            if (product == null) {
                return new ApiResponse(false, "商品存在问题,请联系官方人员!");
            }
            MemberBillSpeedIntegral memberBillSpeedIntegral = MemberBillSpeedIntegral.dao.
                    getMemberBillSpeedIntegralByUserId(userId);
            if (memberBillSpeedIntegral == null) {
                return new ApiResponse(false, "获取用户兑货券信息失败");
            }
            MemberInfo memberInfo = MemberInfo.dao.getMemberInfoByUserId(userId);
            if (memberInfo == null) {
                return new ApiResponse(false, "用户信息暂时无法获取");
            }
            List<ProductSku> productSkulist = ProductSku.dao.getStockByProduct(productId);
            if (CollectionUtils.isEmpty(productSkulist) || CollectionUtils.isNotEmpty(productSkulist) &&
                    productSkulist.get(0).getStockCount() - 1 <= 0) {
                fail("抱歉，此商品SKU库存不足");
            }

            Integer level = memberInfo.getLevel() == null ? 0 : memberInfo.getLevel();
            BigDecimal productIntegralPrice = BigDecimal.valueOf(product.getIntegralPrice());
            MemberCashCouponLog memberCashCouponLog = new MemberCashCouponLog();
            VistorIntegralLog vistorIntegralLog = new VistorIntegralLog();
            if (!level.equals(MemberInfoEnum.SECOND_LEVEL.getCode()) && !level.equals(MemberInfoEnum.THIRD_LEVEL.getCode())) {
                BigDecimal normalIntegral = memberBillSpeedIntegral.getNormalIntegral() == null ? BigDecimal.ZERO :
                        memberBillSpeedIntegral.getNormalIntegral();
                if (BigDecimalUtils.lessThan(normalIntegral, productIntegralPrice)) {
                    return new ApiResponse(false, "积分不足");
                }
                normalIntegral = normalIntegral.subtract(productIntegralPrice);
                memberBillSpeedIntegral.setNormalIntegral(normalIntegral);
                memberBillSpeedIntegral.update();
                vistorIntegralLog.setCommonCoupStatusDescType(
                        userId, productIntegralPrice,normalIntegral,
                        0, "积分兑换商品", 4, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
                vistorIntegralLog.save();
            } else {
                BigDecimal speedIntegral = memberBillSpeedIntegral.getSpeedIntegral() == null ? BigDecimal.ZERO :
                        memberBillSpeedIntegral.getSpeedIntegral();
                if (BigDecimalUtils.lessThan(speedIntegral, productIntegralPrice)) {
                    return new ApiResponse(false, "积分不足");
                }
                speedIntegral = speedIntegral.subtract(productIntegralPrice);
                memberBillSpeedIntegral.setSpeedIntegral(speedIntegral);
                memberBillSpeedIntegral.update();
                memberCashCouponLog.setCommonCoupStatusDescType(
                        userId,  productIntegralPrice,speedIntegral,
                        0, "积分兑换商品", 4, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
            }

            memberCashCouponLog.save();
            memberBillSpeedIntegral.getNormalIntegral();
            UserAddress address = UserAddress.dao.findById(addressId);
            if (address == null) {
                return new ApiResponse(false, "收货地址不存在");
            }
            Order order = new Order();
            order.setUserIdAndPlatformAndRegisterOrderAndAddressAndPayTypeAndPhoneAndDanjiaAndMoneyAndBuyCount(
                    userId, xapp, 0, address, phone, BigDecimal.ZERO, ShopInfo.shop_id, 7,
                    order.State_Wait_Send_Express, 6, 2);
//		    type:类型 state状态表 payType支付方式 paystate支付状态
            order.setCashCoupon(productIntegralPrice);
            order.save();
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderItem(order, productId, num);
            orderItem.save();
//          库存功能
            checkStock(productId + "", orderItem);
            return new ApiResponse(true, "商品兑换成功");
        } catch (
                Exception ex) {
            ex.printStackTrace();
            return new ApiResponse(true, "兑换失败");
        }

    }


    public void checkStock(String productId, OrderItem orderItem) {
        if (StringUtil.isNotBlank(productId)) {
            ProductSku sku = ProductSku.dao.findById(productId);
            if (sku != null) {
                if (orderItem != null) {
                    orderItem.setSkuId(sku.getSkuId());
                    orderItem.setSkuText(sku.getSkuText());
                    orderItem.setSkuCode(sku.getSkuCode());
                    orderItem.setUnitPrice(sku.getPrice());
                }
                //减少库存
                sku.setStockCount(sku.getStockCount() - orderItem.getNums());
                //增加销售量
                sku.setSaleCount(sku.getSaleCount() + orderItem.getNums());
                sku.update();
            }
        }
    }

    /**
     * 累计记录
     *
     * @param id
     * @return
     */
    public List getCashCouponLog(String id) {
        List<MemberBillShopLog> commission = MemberBillShopLog.dao.findByUserId(id);
        List<MemberCoinLog> memberCoinLogList = MemberCoinLog.dao.findByByUserId(id);

        ArrayList list = new ArrayList();
        list.removeIf(e -> e.getClass().getName().equals("java.util.ArrayList"));
        return memberCoinLogList;

//    /*    list.addAll(commission);
//       list.addAll(memberCoinLogList);
//        JSONArray json = new JSONArray();
//        String s = JSON.toJSONString(commission);
//        JSONObject jsonObject=JSONObject.parseObject(String.valueOf(memberCoinLogList));
//        JSONArray arry=JSONArray.fromObject(list);

        //CollectionsSort comparator=new CollectionsSort();
        //Collections.sort(list, comparator);
    }


    public List<MemberOrder> getCashCouponLogList(String userId) {
        List<Order> orderList = Order.dao.getOrderListByUserIdAndStatus(null, userId + "");
        List<MemberOrder> memberOrderlList = MemberOrder.dao.findByOrder(userId);
        Map<String, Order> map = orderList.stream().filter(order -> order.
                getId() != null).collect(Collectors.toMap(Order::getId, a -> a,
                (k1, k2) -> k1));
        List<MemberOrder> collect = memberOrderlList.stream().filter(memberOrder -> memberOrder.getOrderId()
                != null && map.get(memberOrder.getOrderId()) != null).collect(Collectors.toList());
        return collect;
    }

    /**
     * 校验字符串是否是纯数字
     *
     * @param str 数字字符串
     * @return boolean
     */
    public static boolean isInteger(String str) {
        String s = "^[-+]?[\\d]*$";
        Pattern pattern = Pattern.compile(s);
        return pattern.matcher(str).matches();
    }

    /**
     * 校验是否过大
     *
     * @param id
     * @param speedIntegral
     * @return
     */
    public ApiResponse exchangeBillOfShopping(String id, BigDecimal speedIntegral) {
        boolean integerValue = isIntegerValue(speedIntegral);
        if (!integerValue) {
            return new ApiResponse(false, "兑货券输入的值只能为整数", "兑货券输入的值只能为整数");
        }
        Map map = new HashMap();
        map.put("coin", 0);
        map.put("billOfShop", 0);
        if (speedIntegral == null) {
            return new ApiResponse(false, "兑货券不能为空或者0");
        }
        MemberInfo memberInfo = MemberInfo.dao.getMemberFankeInfoByUserId(id);
        if (null == memberInfo || memberInfo.getLevel() == 0) {
            return new ApiResponse(false, "游客不能可以进行兑货券兑换功能", map);
        }
//      积分兑换金币比例
        MemberLevel memberLevel = MemberLevel.dao.getMemberLevel(MemberInfoEnum.THIRD_LEVEL.getCode());
        if (memberLevel == null || memberLevel.getIntegralExchangeCoinRate() == null ||
                memberLevel.getIntegralExchangeCoinProportion() == null ||
                memberLevel.getIntegralExchangeProductProportion() == null) {
            return new ApiResponse(false, "暂时无法兑换", map);
        }
//      所有兑货券
        MemberBillSpeedIntegral memberBillSpeedIntegral = MemberBillSpeedIntegral.dao.getMemberBillSpeedIntegralByUserId(id);
        BigDecimal speedIntegralCount = BigDecimal.ZERO;
        if (memberBillSpeedIntegral != null) {
            speedIntegralCount = memberBillSpeedIntegral.getSpeedIntegral() == null ? BigDecimal.ZERO : memberBillSpeedIntegral.getSpeedIntegral();
        }
        if (BigDecimalUtils.lessThan(speedIntegralCount, speedIntegral)) {
            return new ApiResponse(false, "兑货券太少无法兑换", map);
        }
        ApiResponse apiResponse = calc(memberLevel, speedIntegral);
        return apiResponse;
    }

    /**
     * 积分兑换金币和兑货券功能
     *
     * @param
     * @param
     * @+
     */
    @Before(Tx.class)
    public ApiResponse exchangeCoin(String userId, BigDecimal speedIntegral) {
        ApiResponse convertibleApiResponse = exchangeBillOfShopping(userId, speedIntegral);
        if (convertibleApiResponse.isState() == false) {
            return convertibleApiResponse;
        }

//      所有兑货券兑换产生的金币和提货券
        MemberInfo memberInfo = MemberInfo.dao.getMemberInfoByUserId(userId);
        MemberLevel memberLevel = MemberLevel.dao.getMemberLevel(memberInfo.getLevel());
        ApiResponse calc = calc(memberLevel, speedIntegral);
        if (calc.isState() == false) {
            return calc;
        }
        Map completeExchange = (Map) calc.getData();
        String coin = completeExchange.get("coin") == null ? "0" : completeExchange.get("coin") + "";
        String billOfShop = completeExchange.get("billOfShop") == null ? "0" : completeExchange.get("billOfShop") + "";
        String reserve = completeExchange.get("reserve") == null ? "0" : completeExchange.get("reserve") + "";

        BigDecimal incrementCoin = new BigDecimal(coin);
        BigDecimal incrementBillOfShopping = new BigDecimal(billOfShop);
        BigDecimal incrementReserve = new BigDecimal(reserve);

//      剩余积分memberCashCouponLog
        MemberBillSpeedIntegral memberBillSpeedIntegral = MemberBillSpeedIntegral.dao.getMemberBillSpeedIntegralByUserId(userId);
//      金币(包含已经增加的)
        BigDecimal completeCoinBalance = memberBillSpeedIntegral.getCoin() == null ? BigDecimal.ZERO :
                memberBillSpeedIntegral.getCoin().add(incrementCoin);
//      提货券
        BigDecimal completeBillOfShop = memberBillSpeedIntegral.getBillCoupon() == null ? BigDecimal.ZERO :
                memberBillSpeedIntegral.getBillCoupon().add(incrementBillOfShopping);
//      准备金
        BigDecimal completeReserve = memberBillSpeedIntegral.getReverse() == null ? BigDecimal.ZERO :
                memberBillSpeedIntegral.getReverse().add(incrementReserve);
//      减掉本次以后剩下的积分
        BigDecimal completeSpeedIntegral = memberBillSpeedIntegral.getSpeedIntegral().subtract(speedIntegral);
        memberBillSpeedIntegral.setSpeedIntegralAndCoinAndBillCoupon(completeSpeedIntegral, completeCoinBalance,
                completeBillOfShop, completeReserve);
        memberBillSpeedIntegral.update();

        MemberCashCouponLog memberCashCouponLog = new MemberCashCouponLog();
        memberCashCouponLog.setCommonCoupStatusDescType(userId, speedIntegral, completeSpeedIntegral,
                0, "积分兑换佣金和提货券", 3, incrementCoin, incrementBillOfShopping, incrementReserve);
        memberCashCouponLog.save();


        BigDecimal reserveBd = new BigDecimal(reserve);
        CompanyReserve companyReserve = new CompanyReserve();
        companyReserve.setCompanyReserve(userId, reserveBd);
        companyReserve.save();
        List<Company> companyList = Company.dao.findAll();
        Optional<Company> first = companyList.stream().filter(company -> new Integer("2") == company.getType()).findFirst();
        if (first.isPresent()) {
            Company company = first.get();
            BigDecimal count = company.getCount();
            BigDecimal add = count.add(reserveBd);
            company.setCount(add);
            company.setUpdateTime(new Date().getTime());
            company.update();
        } else {
            Company company = new Company();
            company.setId(UUIDUtils.getUUIDInOrderId() + "");
            company.setType(2);
            company.setCount(reserveBd);
            Long date = new Date().getTime();
            company.setCreateTime(date);
            company.setUpdateTime(date);
            company.save();
        }


        JSONObject jsonObject = new JSONObject();
        jsonObject.put("reserve", completeReserve);
        jsonObject.put("remainSpeedIntegral", speedIntegral);
        jsonObject.put("coin", memberBillSpeedIntegral.getCoin());
        jsonObject.put("billOfLading", memberBillSpeedIntegral.getBillCoupon());
        return new ApiResponse(true, "兑换成功", jsonObject);
    }

    /**
     * 校验和兑换的过程
     *
     * @param memberLevel
     * @param speedIntegral
     * @return
     */
    public ApiResponse calc(MemberLevel memberLevel, BigDecimal speedIntegral) {
        if (BigDecimalUtils.lessThan(speedIntegral, new BigDecimal("5"))) {
            return new ApiResponse(false, "最少兑换5个积分");
        }
        Map map = new HashMap();

//      准备金
        int reserves = memberLevel.getReserveProportion() == null ? 0 : memberLevel.getReserveProportion();
        double reserveProportion = percent(reserves, 100);
        BigDecimal reservesBalance = speedIntegral.multiply(BigDecimal.valueOf(reserveProportion));

//      除了准备金剩余的兑货券
        speedIntegral = speedIntegral.subtract(reservesBalance);

//      兑换金币(金币折合成积分有多少个)
        int integralExchangeCoinProportion = memberLevel.getIntegralExchangeCoinProportion();
        double integralExchangeCoinPercent = percent(integralExchangeCoinProportion, 100);
        BigDecimal convertible = speedIntegral.multiply(BigDecimal.valueOf(integralExchangeCoinPercent));
//      积分转金币汇率
        int integralExchangeCoinRate = memberLevel.getIntegralExchangeCoinRate();
        double integralExchangeCoinRatePercent = percent(integralExchangeCoinRate, 100);
        BigDecimal coin = convertible.multiply(BigDecimal.valueOf(integralExchangeCoinRatePercent));

//      提货券有多少个
        int integralExchangeProductProportion = memberLevel.getIntegralExchangeProductProportion()
                == null ? 0 : memberLevel.getIntegralExchangeProductProportion();
        double integralExchangeProductPercent = percent(integralExchangeProductProportion, integralExchangeCoinProportion);
        BigDecimal billOfShop = coin.multiply(BigDecimal.valueOf(integralExchangeProductPercent));
        map.put("coin", coin);
        map.put("billOfShop", billOfShop);
        map.put("reserve", reservesBalance);
        return new ApiResponse(true, "获取成功", map);
    }


    private boolean isIntegerValue(BigDecimal bd) {
        boolean ret;

        try {
            bd.toBigIntegerExact();
            ret = true;
        } catch (ArithmeticException ex) {
            ret = false;
        }

        return ret;
    }
}












